#include "../include/OgreFace.h"

//initialize some static vars
Mutex OgreFace::s_mutex;
EventSystem::EventManager OgreFace::m_EventManager;
OgreFace* Simpleton<OgreFace>::s_singleton=0;

//-----------------------------------------------------------------------
OgreFace::~OgreFace()
{
	// Destroy engine
    //THROW_ON_ERROR(smVideoDisplayDestroy(&video_display_handle));
	THROW_ON_ERROR(smEngineDestroy(&engine_handle));
	
	smAPIQuit();
}
//-----------------------------------------------------------------------
OgreFace::OgreFace()
{
	
	Ogre::LogManager::getSingletonPtr()->logMessage("*** Initializing FACE-TRACKING ***");

	#   ifdef _DEBUG
    // Log API debugging information to a file
    THROW_ON_ERROR(smLoggingSetFileOutputEnable(SM_API_TRUE));

    // Hook up log message callback
    THROW_ON_ERROR(smLoggingRegisterCallback(0,OgreFace::receiveLogMessage));
#   endif

    // Get the version
    int major, minor, maint;
    THROW_ON_ERROR(smAPIVersion(&major, &minor, &maint));
    //cout << endl << "API VERSION: " << major << "." << minor << "." << maint << "." << endl << endl;
    // Print detailed license info
    char *buff;
    int size;
    THROW_ON_ERROR(smAPILicenseInfoString(0,&size,SM_API_TRUE));
    buff = new char[size];
    THROW_ON_ERROR(smAPILicenseInfoString(buff,&size,SM_API_TRUE));
    //cout << "LICENSE: " << buff << endl << endl;
    // Determine if non-commercial restrictions apply
    const bool non_commercial_license = smAPINonCommercialLicense() == SM_API_TRUE;

    // Initialize the API
    THROW_ON_ERROR(smAPIInit());

#   ifdef _DEBUG
    // Get the path to the logfile
    smStringHandle logfile_path_handle = 0;
    THROW_ON_ERROR(smStringCreate(&logfile_path_handle));
    THROW_ON_ERROR(smLoggingGetPath(logfile_path_handle));
    int buf_len = 0;
    unsigned short *buf = 0;
    THROW_ON_ERROR(smStringGetBufferW(logfile_path_handle,(wchar_t **)&buf,&buf_len));
    //wcout << "Writing log to file: " << wstring((wchar_t *)buf) << endl;
    THROW_ON_ERROR(smStringDestroy(&logfile_path_handle));
#   endif

    // Register the WDM category of cameras
    THROW_ON_ERROR(smCameraRegisterType(SM_API_CAMERA_TYPE_WDM));

    engine_handle = 0;
    smCameraHandle camera_handle = 0;
    if (non_commercial_license)
    {
        // Create a new Head-Tracker engine that uses the camera
        THROW_ON_ERROR(smEngineCreate(SM_API_ENGINE_LATEST_HEAD_TRACKER,&engine_handle));
    }

	THROW_ON_ERROR(smHTRegisterHeadPoseCallback(engine_handle,0,OgreFace::receiveHeadPose));

	// Create and show a video-display window
    video_display_handle = 0;
    //THROW_ON_ERROR(smVideoDisplayCreate(engine_handle,&video_display_handle,0,TRUE));

    // Setup the VideoDisplay
    //THROW_ON_ERROR(smVideoDisplaySetFlags(video_display_handle,SM_API_VIDEO_DISPLAY_HEAD_MESH));

	THROW_ON_ERROR(smEngineStart(engine_handle));
	
}
//-----------------------------------------------------------------------
void OgreFace::addListener(EventSystem::EventListener& eventListener)
{
	m_EventManager.addListener(eventListener);
}
//-----------------------------------------------------------------------
void  OgreFace::receiveHeadPose(void *,smEngineHeadPoseData head_pose, smCameraVideoFrame video_frame)
{
	Lock lock(s_mutex);

	

	// Get info including data pointer to original image from camera
	smImageInfo video_frame_image_info;
	THROW_ON_ERROR(smImageGetInfo(video_frame.image_handle, &video_frame_image_info)); // reentrant, so ok
	EventSystem::EventPtr ptr = EventSystem::makeDataEvent(EventSystem::Event::TypeId(),head_pose);
	m_EventManager.broadcastEvent(ptr);
}